package com.ruicar.afs.cloud.afscase.mq.receiver.processor;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.entity.*;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoTempService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolHistoryService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.approvetask.vo.WorkflowAppointVO;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseRedundantInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseRedundantInfoService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveInformInfoService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.vo.CaseLogInfo;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.afscase.processor.enums.WorkflowType;
import com.ruicar.afs.cloud.afscase.processor.service.ChangeAssetsWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalTaskSubmitVO;
import com.ruicar.afs.cloud.afscase.remind.entity.CaseRemindDetail;
import com.ruicar.afs.cloud.afscase.remind.service.RemindService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.common.modules.dto.mq.approve.ApproveSpecialSubmitInfo;
import com.ruicar.afs.cloud.common.modules.dto.mq.approve.ComAttachmentFileDto;
import com.ruicar.afs.cloud.common.mq.rabbit.listener.AfsMqBizProcessor;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.service.ComAttachmentFileService;
import com.ruicar.afs.cloud.seats.entity.UserCollocation;
import com.ruicar.afs.cloud.seats.service.UserCollocationService;
import com.ruicar.afs.cloud.seats.util.PostStatus;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description: 信审资产变更、复议
 * @author jiaqi.guo
 * @created 2020/7/28 13:04
 * @version 1.0
 */
@AllArgsConstructor
@Slf4j
@Component
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit",name="enable")
public class ApproveSpecialProcessor implements AfsMqBizProcessor<ApproveSpecialSubmitInfo> {

    private CaseBaseInfoService caseBaseInfoService;
    private WorkProcessScheduleInfoTempService  scheduleInfoTempService;
    private ChangeAssetsWorkflowService workflowService;
    private WorkTaskPoolHistoryService historyService;
    private ApproveInformInfoService informInfoService;
    private WorkTaskPoolService workTaskPoolService;
    private CaseRedundantInfoService redundantInfoService;
    private UserCollocationService userCollocationService;
    private WorkProcessScheduleInfoService workProcessScheduleInfoService;
    private RemindService remindService;
    private ComAttachmentFileService comAttachmentFileService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processMessage(ApproveSpecialSubmitInfo entity)   {
        CaseLogInfo caseLogInfo= new CaseLogInfo();
        String bool=ResultBooleanEnum.TRUE.getCode();
        try{
            this.saveChangeAssetsData(entity);
            caseLogInfo.setApplyNo(entity.getApplyNo());
            caseLogInfo.setResult(ResultBooleanEnum.TRUE.getCode());
            log.info("变更数据落库成功:{}",entity.getApplyNo());
        }catch ( Exception e){
            bool=ResultBooleanEnum.FALSE.getCode();
            caseLogInfo.setApplyNo(entity.getApplyNo());
            caseLogInfo.setResult(ResultBooleanEnum.FALSE.getCode());
            log.info("变更数据落库失败:{}",entity.getApplyNo());
        }
        //资产变更落库结果通知
        informInfoService.changeAssetsResult(caseLogInfo);
        //变更数据落库成功
        if(bool.equals(ResultBooleanEnum.TRUE.getCode())){
            CaseBaseInfo baseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
            .eq(CaseBaseInfo::getApplyNo,entity.getApplyNo()));
            List<WorkTaskPoolHistory>  hisList=historyService.list(Wrappers.<WorkTaskPoolHistory>query().lambda()
                    .eq(WorkTaskPoolHistory::getStageId,baseInfo.getNormalApproveFlowId())
            .eq(WorkTaskPoolHistory::getFirstNode,WhetherEnum.YES.getCode())
            .orderByDesc(WorkTaskPoolHistory::getCreateTime));
            /**流程提交*/
            if(StringUtils.isNotBlank(entity.getApproveInformDto().getStageId())){
                WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(Long.parseLong(entity.getApproveInformDto().getStageId()));
                WorkTaskPool pool = workTaskPoolService.getOne(
                        Wrappers.<WorkTaskPool>lambdaQuery()
                                .eq(WorkTaskPool::getStageId, entity.getApproveInformDto().getStageId())
                );
                CaseApproveRecord record = new CaseApproveRecord();
                record.setStageId(info.getStageId());
                record.setApplyNo(info.getApplyNo());
                record.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.MODIFY_SUBMIT));
                record.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.MODIFY_SUBMIT));
                record.setDisposeNode(pool.getTaskNodeId());
                record.setDisposeNodeName(pool.getTaskNodeName());
                record.setApproveStartTime(pool.getStartTime());
                record.setApproveEndTime(new Date());
                record.setApproveType(ApproveTypeEnum.PROCESS.getValue());
                record.setDisposeStaff(pool.getApproveStaffName());
                record.setApproveRemark(entity.getApproveInformDto().getLeaveMessage());
                workflowService.submit(NormalTaskSubmitVO.builder().workFlowInfo(info).workTaskPool(pool).record(record).build());
                if(StringUtils.isNotBlank(entity.getApproveInformDto().getLeaveMessage())){
                    /**修订回复添加留言*/
                    CaseRemindDetail remindDetail =new CaseRemindDetail();
                    remindDetail.setApplyNo(entity.getApplyNo());
                    remindDetail.setDisposeUser(pool.getApproveStaffName());
                    remindDetail.setStatus(CancelStatusEnum.EFFECTIVE.getCode());
                    remindDetail.setDisposeTime(new Date());
                    remindDetail.setRemindContent(entity.getApproveInformDto().getLeaveMessage());
                    remindDetail.setUseScene(UseSceneEnum.CHANGE_ASSETS.getValue());
                    remindService.save(remindDetail);
                }
            }else{
                //发起流程
                WorkflowAppointVO appointVO = new WorkflowAppointVO();
                if(CollectionUtils.isNotEmpty(hisList)){
                    WorkProcessScheduleInfoTemp temp = new WorkProcessScheduleInfoTemp();
                    temp.setAfsFlowKey(WorkflowType.CHANGE_ASSETS.getAfsFlowKey());
                    temp.setApplyNo(entity.getApplyNo());
                    String name=getStaffName(hisList.get(0).getApproveStaff());
                    temp.setAppointHandler(name);
                    temp.setStartTime(new Date());
                    scheduleInfoTempService.saveWithNewTransactional(temp);

                    appointVO.setApplyNo(entity.getApplyNo());
                    appointVO.setAppointStaff(name);
                    this.startAppointFlowByPerson(appointVO,temp);

                }else{
                    log.info("资产变更流程未能发起:{}",entity.getApplyNo());
                }

            }
        }
        return true;
    }
    @Override
    public MqTransCode getCode() {
        return MqTransCode.AFS_POS_APPLY_CASE_CTM_ASSETS_RECONSIDER;
    }
    /**
     * @description: 解析保存变更数据
     * @author jiaqi.guo
     * @created 2020/7/28 13:32
     * @version 1.0
     */
    public void  saveChangeAssetsData(ApproveSpecialSubmitInfo entity){
        JSONObject dataJson=entity.getChangeDataJson();
        CaseRedundantInfo redundantInfo= redundantInfoService.getOne(Wrappers.<CaseRedundantInfo>query().lambda()
                .eq(StringUtils.isNotBlank(entity.getApplyNo()),CaseRedundantInfo::getApplyNo,entity.getApplyNo()));
        /**  2.14解析影像文件ComAttachmentFile  **/
        ArrayList<ComAttachmentFile> comAttachmentFileArrayList = this.parseComAttachmentFile(entity);
        comAttachmentFileService.saveOrUpdateBatch(comAttachmentFileArrayList,comAttachmentFileArrayList.size());
        log.info("影像文件add成功！！！");
        if(ObjectUtils.isNotEmpty(dataJson)){
            if(ObjectUtils.isNotEmpty(redundantInfo)){
                redundantInfo.setChangeAssetsRepeat(dataJson.toString());
                redundantInfoService.updateById(redundantInfo);
                log.info("资产变更冗余数据update完成！！！");
            }else{
                CaseRedundantInfo caseRedundantInfo= new CaseRedundantInfo();
                caseRedundantInfo.setApplyNo(entity.getApplyNo());
                caseRedundantInfo.setChangeAssetsRepeat(dataJson.toString());
                redundantInfoService.save(redundantInfo);
                log.info("资产变更冗余数据add完成！！！");
            }
        }else{
           throw  new AfsBaseException("接收变更数据为null/无案件信息");
        }
    }
    /**
     * @description:资产变更指定处理人
     * @author jiaqi.guo
     * @created 2020/7/28 15:55
     * @version 1.0
     */
    public void startAppointFlowByPerson( WorkflowAppointVO appointVO,WorkProcessScheduleInfoTemp temp){
        log.info("########################## 资产变更指定处理人流程发起 Start ###############");
        workflowService.start(temp);
        log.info("########################## 资产变更指定处理人流程发起 End###############");

    }
    /**
     * 获取代理组长信息 根据在岗状态分配人员
     * @param staffName
     * @return
     */
    public String getStaffName(String staffName) {
        String  name=staffName;
        //获取原处理人信息
        UserCollocation userCollocation = userCollocationService.getOne(
                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, staffName)
        );
        if(ObjectUtils.isNotEmpty(userCollocation)){
            if(userCollocation.getPostStatus().equals(PostStatus.NO.getCode())){
                /**离岗取代理人*/
                if(StringUtils.isNotBlank(userCollocation.getAgentLoginName())){
                    /**获取代理人信息*/
                    UserCollocation  userAgent= userCollocationService.getOne(Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, userCollocation.getAgentLoginName()));
                    /**有配置代理人并且在岗*/
                    if(ObjectUtils.isNotEmpty(userAgent)&&userAgent.getPostStatus().equals(PostStatus.YES.getCode())){
                       name=userAgent.getLoginName();
                    }
                }
            }
        }
        log.info("代理组长信息响应 ==> {}", name);
        return name;
    }
    /**
     * 影像资料解析
     * @param entity
     * @return
     */
    private ArrayList<ComAttachmentFile> parseComAttachmentFile(ApproveSpecialSubmitInfo entity ) {
        ArrayList<ComAttachmentFile> comAttachmentFileArrayList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(entity.getComAttachmentFileListDto())) {
            for (ComAttachmentFileDto attachmentFileDto : entity.getComAttachmentFileListDto()) {
                if (ObjectUtils.isEmpty(attachmentFileDto.getBusiNo()) || ObjectUtils.isEmpty(attachmentFileDto.getBelongNo())) {
                    throw new AfsBaseException("业务编号:" + attachmentFileDto.getBusiNo() + ",所属业务编号:" + attachmentFileDto.getBelongNo() + "不能为空");
                }
                ComAttachmentFile comAttachmentFile = new ComAttachmentFile();
                BeanUtils.copyProperties(attachmentFileDto, comAttachmentFile);
                comAttachmentFileArrayList.add(comAttachmentFile);

            }
        }
        return  comAttachmentFileArrayList;
    }
}
